﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Windows.Forms;
using CD2WebAudio3Lib;
using System.IO;
using System.Drawing;
using System.Collections;

namespace CD2WebAudio3UI.Forms
{
    public partial class frmMain : Form
    {
        private main_functions m_Functions = main_functions.Get_Instance();
        private bool m_Loaded = false;
        private wave_class m_Wave = null;
        private bool m_Cancel = false;
        private mp3_creator m_MP3;
        private bool m_InProgress = false;
        private bool m_Locked = false;
        private string m_ProgressMessage = string.Empty;


        /// <summary>
        /// Constructor
        /// </summary>
        public frmMain()
        {
            InitializeComponent();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                Application.Exit();
            }
            finally { }
        }

        /// <summary>
        /// Handles form load event.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmMain_Load(object sender, EventArgs e)
        {
            flpMainPanel.BackColor = Color.FromArgb(255, 42, 58, 87);
            
            Load_Drives();
            
            // load saved values for unbindable controls
            Load_Settings();

            show_File_Name();
            show_Copyright_Sample();
            set_cd_or_audio_file();

            // finally, enable timer
            tmrCheckCD.Enabled = rbUseCD.Checked;

            // finally
            m_Loaded = true;
        }

        /// <summary>
        /// Loads CD drives into combo box.
        /// </summary>
        private void Load_Drives()
        {
            cmbDrive.Items.AddRange(m_Functions.Load_Drives());
            if (cmbDrive.Items.Count > 0) cmbDrive.SelectedIndex = 0;
        }

        /// <summary>
        /// Loads saved settings during form load.
        /// </summary>
        private void Load_Settings()
        {

            main_settings settings = new main_settings();

            // general
            this.Location = settings.MainLocation;
            chkUpload.Checked = settings.PublishFiles;
            chkClose.Checked = settings.CloseWhenFinished;
            chkShutdown.Checked = settings.ShutDownWhenFinished;
            rbUseAudioFile.Checked = settings.UseAudioFile;
            chkPublishSermon.Checked = settings.PublishSermon;

            // mp3
            cmbMP3BitRate.SelectedIndex = settings.MP3BitRate;
            chkPublishMP3.Checked = settings.PublishMP3;
            txtMP3URL.Text = settings.MP3Url;
            txtMP3Username.Text = settings.MP3Username;
            txtMP3Password.Text = settings.MP3Password;
            txtMP3Port.Text = settings.MP3Port;

            // output folder
            string output = settings.OutputFolder;
            if ((output.Length == 0) || (!Directory.Exists(output)))
            {
                output = m_Functions.CommonAppData + "Output";
            }
            txtDestination.Text = output;
            txtCopyright.Text = settings.CopyrightText;
            txtPresetAuthors.Text = settings.PresetAuthors;
            txtPresetSuffixes.Text = settings.PresetSuffixes;

            // authors
            set_Authors_List();
            cmbAuthor.Text = settings.LastAuthor;

            // suffixes
            set_Suffix_List();
            cmbSuffix.Text = settings.LastSuffix;

        }

        private void tmrCheckCD_Tick(object sender, EventArgs e)
        {
            try
            {
                tmrCheckCD.Enabled = false;

                track_list list = m_Functions.Load_Tracks(cmbDrive.Text);
                if (list.ClearList)
                {
                    lvTracks.Items.Clear();
                    if (list.Items != null) lvTracks.Items.AddRange(list.Items);

                }

                display_Total_Time();
            }
            finally
            {
                tmrCheckCD.Enabled = true;
            }
        }

        /// <summary>
        /// Displays the total time of the selected tracks in the status bar.
        /// </summary>
        private void display_Total_Time()
        {
            lblStatus.Text = "Total time:  " + m_Functions.Seconds_To_Time(get_Total_Seconds());
        }

        private int get_Total_Seconds()
        {
            int seconds = 0;

            foreach (ListViewItem lvi in lvTracks.Items)
            {
                if (lvi.Checked)
                {
                    if (lvi.SubItems[2].Text.ToLower().CompareTo("audio") == 0)
                    {
                        seconds += int.Parse(lvi.SubItems[3].Text);
                    }
                }
            }

            return seconds;
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            Save_Settings();
        }

        /// <summary>
        /// Saves settings when the form closes.
        /// </summary>
        private void Save_Settings()
        {
            main_settings settings = new main_settings();

            // general
            settings.MainLocation = this.Location;
            settings.PublishFiles = chkUpload.Checked;
            settings.CloseWhenFinished = chkClose.Checked;
            settings.ShutDownWhenFinished = chkShutdown.Checked;
            settings.UseAudioFile = rbUseAudioFile.Checked;
            settings.PublishSermon = chkPublishSermon.Checked;

            // mp3
            settings.CreateMP3 = true;
            settings.MP3BitRate = cmbMP3BitRate.SelectedIndex;
            settings.PublishMP3 = chkPublishMP3.Checked;
            settings.MP3Url = txtMP3URL.Text;
            settings.MP3Username = txtMP3Username.Text;
            settings.MP3Password = txtMP3Password.Text;
            settings.MP3Port = txtMP3Port.Text;

            // output folder
            settings.OutputFolder = txtDestination.Text;
            settings.CopyrightText = txtCopyright.Text;

            // authors
            settings.PresetAuthors = txtPresetAuthors.Text;
            settings.LastAuthor = cmbAuthor.Text;

            // suffixes
            settings.PresetSuffixes = txtPresetSuffixes.Text;
            settings.LastSuffix = cmbSuffix.Text;

            settings.Save();

        }

        private void dtpDate_ValueChanged(object sender, EventArgs e)
        {
            show_File_Name();
        }

        private void show_File_Name()
        {
            string s = dtpDate.Value.ToString("yyyyMMdd");
            s += cmbSuffix.Text;
            if (!s.EndsWith(".")) s += ".";
            s += "mp3";
            lblFileName.Text = s;
        }

        private void cmbSuffix_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (m_Loaded) show_File_Name();
        }

        private void txtPresetAuthors_Leave(object sender, EventArgs e)
        {
            set_Authors_List();
        }

        private void set_Authors_List()
        {
            string[] authors = txtPresetAuthors.Text.Split(new char[] { (char)13, (char)10 }, StringSplitOptions.RemoveEmptyEntries);
            cmbAuthor.Items.Clear();
            cmbAuthor.Items.AddRange(authors);
        }

        private void set_Suffix_List()
        {
            string[] suffixes = txtPresetSuffixes.Text.Split(new char[] { (char)13, (char)10 }, StringSplitOptions.RemoveEmptyEntries);
            cmbSuffix.Items.Clear();
            cmbSuffix.Items.AddRange(suffixes);
        }

        private void txtPresetSuffixes_Leave(object sender, EventArgs e)
        {
            set_Suffix_List();
        }

        private void txtCopyright_TextChanged(object sender, EventArgs e)
        {
            show_Copyright_Sample();
        }

        private void show_Copyright_Sample()
        {
            lblCopyright.Text = "Copyright © " + DateTime.Today.Year.ToString() + " " + txtCopyright.Text;
        }

        private void btnStartStop_Click(object sender, EventArgs e)
        {
            try
            {
                if (btnStartStop.Text.ToLower().CompareTo("start") == 0)
                {
                    tmrCheckCD.Enabled = false;

                    // initialize
                    m_Wave = null;
                    m_MP3 = null;
                    m_InProgress = true;
                    m_Cancel = false;

                    // try to connect to the web
                    if ((chkUpload.Checked) && (chkPublishMP3.Checked))
                    {
                        resolve_ftp.Resolve_FTP_Address(txtMP3URL.Text, "", "", txtMP3Port.Text);
                    }

                    // create the files
                    create_Audio_Files();
                    if (chkUpload.Checked) publish_Audio_Files();

                    // clean-up
                    m_Wave = null;
                    m_MP3 = null;

                    if (chkShutdown.Checked)
                    {
                        frmShutdown frm = new frmShutdown();
                        frm.ShowDialog();
                        return;
                    }
                    else if (chkClose.Checked)
                    {
                        frmShutdown frm = new frmShutdown();
                        frm.JustClose = true;
                        frm.ShowDialog();
                        return;
                    }

                }
                else  // canceling
                {
                    m_Cancel = true;
                    if (m_Wave != null) m_Wave.Cancel = true;
                    if (m_MP3 != null) m_MP3.Cancel = true;
                }

            }
            finally
            {
                // to prepare for another attempt
                if (m_InProgress)
                {
                    Load_Drives();
                    m_InProgress = false;
                }

                reset_Progress(false);
                tmrCheckCD.Enabled = true;
                enable_Form(true);
                btnStartStop.Text = "Start";
                lblOK2Remove.Visible = false;
                m_Functions.TempFiles.Delete();
                m_Functions.TempFiles = null;

                System.GC.Collect();
            }
        }

        /// <summary>
        /// Create selected audio files.
        /// </summary>
        private void create_Audio_Files()
        {

            if (!Passed_Check()) return;

            // temp wave file name
            string waveFileName = string.Empty;

            // set up cancel button
            btnStartStop.Text = "Stop";
            lblOK2Remove.Visible = false;
            m_Cancel = false;
            reset_Progress(true);
            this.Refresh();
            Application.DoEvents();

            // other initialization stuff
            TheApp.Cancel = false;
            enable_Form(false);

            if (rbUseCD.Checked)
            {
                // get temp file name for ripping
                waveFileName = m_Functions.Get_Temp_FileName(".wav", false);

                // copy from CD to wave file
                rip_CD(waveFileName);
                if (m_Cancel) return;
            }
            else
            {
                waveFileName = txtAudioFile.Text;
            }

            // create mp3 file
            reset_Progress(true);

            string copyright = string.Format("Copyright © {0} {1}", dtpDate.Value.Year.ToString(), txtCopyright.Text);

            string mp3FileName = m_Functions.Get_Target_File_Name(txtDestination.Text, dtpDate.Value, cmbSuffix.Text, ".mp3", true);
            uint mp3BitRate = uint.Parse(cmbMP3BitRate.SelectedItem.ToString());
            m_ProgressMessage = "Creating MP3 . . .";
            m_MP3 = new mp3_creator();
            //m_MP3.MP3Progress += new MP3ProgressHandler(Percent_Progress);
            m_MP3.Create_MP3(waveFileName, mp3FileName, mp3BitRate, cmbAuthor.Text, txtTitle.Text, copyright, get_Total_Seconds() * 1000);
            if (m_Cancel) return;

            TheApp.Wait(2);

        }

        /// <summary>
        /// Resets and optionally hides the progress controls
        /// </summary>
        /// <param name="pVisible"></param>
        private void reset_Progress(bool pVisible)
        {
            try
            {
                pbProgressBar.Visible = pVisible;
                lblMessage.Visible = pVisible;
                lblMessage.Text = "";
                pbProgressBar.Value = 0;
            }
            catch
            {
                TheApp.Wait(2);
                try
                {
                    pbProgressBar.Visible = pVisible;
                    lblMessage.Visible = pVisible;
                    lblMessage.Text = "";
                    pbProgressBar.Value = 0;
                }
                catch { }
            }
        }

        /// <summary>
        /// Checks the data before starting to convert the CD to Web Audio.
        /// </summary>
        /// <returns>true if passes check, else false<></returns>
        private bool Passed_Check()
        {
            if (rbUseCD.Checked)
            {
                if (lvTracks.CheckedItems.Count == 0) return false;
            }
            else
            {
                if (!File.Exists(txtAudioFile.Text)) return false;
            }

            if (txtTitle.Text.Trim().Length == 0)
            {
                txtTitle.Text = dtpDate.Value.ToString("yyyy-MM-dd") + " " + cmbSuffix.Text.Trim();   //'Trim(format(dtpDate.Value, "Short Date") & " " & cmbAMPM.Text)
            }

            //check for destination folder
            if (!Directory.Exists(txtDestination.Text))
            {
                // try to create it
                try
                {
                    Directory.CreateDirectory(txtDestination.Text);
                }
                catch { }

                if (!Directory.Exists(txtDestination.Text))
                {
                    MessageBox.Show("The Destination Folder does not exist.  Open the settings and select the correct Destination Folder", TheApp.Title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return false;
                }
            }

            return true;

        }

        /// <summary>
        /// Sets which controls are enabled.
        /// </summary>
        /// <param name="pEnable">true to enable all controls, false to disable some.</param>
        private void enable_Form(bool pEnable)
        {
            // mousepointer
            if (pEnable)
            {
                this.Cursor = Cursors.Default;
                btnStartStop.Cursor = Cursors.Default;
                chkClose.Cursor = Cursors.Default;
                chkShutdown.Cursor = Cursors.Default;
            }
            else
            {
                this.Cursor = Cursors.WaitCursor;
                btnStartStop.Cursor = Cursors.AppStarting;
                chkClose.Cursor = Cursors.AppStarting;
                chkShutdown.Cursor = Cursors.AppStarting;
            }

            // controls
            lvTracks.Enabled = pEnable;
            txtTitle.Enabled = pEnable;
            txtPassage.Enabled = pEnable;
            cmbDrive.Enabled = pEnable;
            cmbAuthor.Enabled = pEnable;
            cmbSuffix.Enabled = pEnable;
            chkUpload.Enabled = pEnable;
            chkPublishSermon.Enabled = pEnable;
            dtpDate.Enabled = pEnable;
            txtAudioFile.Enabled = pEnable;
            btnBrowseAudioFile.Enabled = pEnable;

            m_Locked = !pEnable;
        }

        /// <summary>
        /// Copy selected tracks from CD to a wave file.
        /// </summary>
        /// <param name="pWaveFileName">The name to use for the wave file.</param>
        private void rip_CD(string pWaveFileName)
        {
            
            if (lvTracks.CheckedIndices.Count > 0)
            {
                // copy from CD to wave file
                m_ProgressMessage = "Copying from CD . . .";

                ArrayList tracks = new ArrayList();
                for (int track = 1; track <= lvTracks.Items.Count; track++)
                {
                    if (lvTracks.Items[track - 1].Checked) tracks.Add(track);
                }

                m_Wave = new wave_class();
                m_Wave.WaveProgress += new WaveProgressHandler(Percent_Progress);
                if (!m_Wave.Rip_To_TempFile(pWaveFileName, tracks, cmbDrive.Text)) return;

                TheApp.Wait(5);
                lblOK2Remove.Visible = true;
                m_Wave = null;
            }
        }

        /// <summary>
        /// Event used to show progress.
        /// </summary>
        /// <param name="pSender"></param>
        /// <param name="pPercent"></param>
        public void Percent_Progress(object pSender, decimal pPercent)
        {
            try
            {
                lblMessage.Text = m_ProgressMessage + " " + pPercent.ToString("##0") + "%";
                pbProgressBar.Value = Convert.ToInt32(pPercent);
            }
            catch { }
        }

        /// <summary>
        /// Event used to show progress for ftp class
        /// </summary>
        /// <param name="pSender"></param>
        /// <param name="pPercent"></param>
        /// <param name="pMessage"></param>
        private void Percent_Progress_With_Message(object pSender, decimal pPercent, string pMessage)
        {
            try
            {
                if (pMessage.Length == 0)
                {
                    lblMessage.Text = m_ProgressMessage + " " + pPercent.ToString("##0") + "%";
                }
                else
                {
                    lblMessage.Text = pMessage;
                }
                pbProgressBar.Value = Convert.ToInt32(pPercent);
                statusStrip1.Refresh();
            }
            catch { }
        }

        private void cmbSuffix_TextChanged(object sender, EventArgs e)
        {
            if (m_Loaded) show_File_Name();
        }

        /// <summary>
        /// Publishes the list of audio files to the ftp server(s).
        /// </summary>
        private void publish_Audio_Files()
        {

            // mp3
            if (m_Cancel) return;
            file_to_publish ftp = null;
            string fn = m_Functions.Get_Target_File_Name(txtDestination.Text, dtpDate.Value, cmbSuffix.Text, ".mp3", false);
            if ((chkPublishMP3.Checked) && (File.Exists(fn)))
            {
                ftp = new file_to_publish("MP3", fn, txtMP3URL.Text, txtMP3Username.Text, txtMP3Password.Text, txtMP3Port.Text);

                TheApp.Wait(2);
                reset_Progress(true);
                m_ProgressMessage = "Publishing " + ftp.Description + " . . .";
                ftp.FTPProgress += new FTPProgressHandler(Percent_Progress_With_Message);
                ftp.Publish();
                TheApp.Wait(2);
            }

            // add sermon to the web site
            if (chkPublishSermon.Checked)
            {

                CD2WebAudio3.info.gracechapelchurch.www.AudioFileData dat = new CD2WebAudio3.info.gracechapelchurch.www.AudioFileData();
                dat.SermonDate = dtpDate.Value.Date;
                dat.DisplayDate = dtpDate.Value.ToString("MMM d, yyyy") + " " + cmbSuffix.Text.Trim();
                dat.Title = txtTitle.Text.Trim();
                dat.Speaker = cmbAuthor.Text.Trim();
                dat.Passage = txtPassage.Text.Trim();
                dat.FileName = dtpDate.Value.ToString("yyyyMMdd") + cmbSuffix.Text.Trim();
                dat.HasMP3 = chkPublishMP3.Checked;
                dat.HasRA = false;

                using (CD2WebAudio3.info.gracechapelchurch.www.newsermon ns = new CD2WebAudio3.info.gracechapelchurch.www.newsermon())
                {
                    int webResult = ns.UploadAudio("CD2WebAudio", "WebPassword", dat);
                }
            }

        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmAbout frm = new frmAbout();
            frm.ShowDialog(this);
        }

        private void rbUseAudioFile_CheckedChanged(object sender, EventArgs e)
        {
            if (m_Loaded) set_cd_or_audio_file();

        }

        private void set_cd_or_audio_file()
        {
            // to reduce flicker
            if (rbUseAudioFile.Checked)
            {
                lvTracks.Visible = false;
                txtAudioFile.Visible = true;
                lblAudioFile.Visible = true;
                btnBrowseAudioFile.Visible = true;
            }
            else
            {
                lblAudioFile.Visible = false;
                txtAudioFile.Visible = false;
                btnBrowseAudioFile.Visible = false;
                lvTracks.Visible = true;
            }

            lblCDDrive.Visible = !rbUseAudioFile.Checked;
            cmbDrive.Visible = !rbUseAudioFile.Checked;

            if (m_Loaded) tmrCheckCD.Enabled = rbUseCD.Checked;
        }

        private void btnBrowseAudioFile_Click(object sender, EventArgs e)
        {
            DialogResult result = openFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                txtAudioFile.Text = openFileDialog1.FileName;
            }
        }

        private void btnDestination_Click(object sender, EventArgs e)
        {
            if (txtDestination.Text.Length > 0)
            {
                if (Directory.Exists(txtDestination.Text))
                {
                    folderBrowserDialog1.SelectedPath = txtDestination.Text;
                }
            }

            DialogResult result = folderBrowserDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                txtDestination.Text = folderBrowserDialog1.SelectedPath;
            }
        }
    }
}
